home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 276-300 / 294 / dnet / amiga / client / getfiles.c < prev    next >
C/C++ Source or Header  |  1995-03-14  |  9KB  |  453 lines

  1.  
  2. /*
  3.  *  GETFILES.C        V1.30
  4.  *
  5.  *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  *
  7.  *
  8.  *  GETFILES [-Nnetid] [-dlocaldir] [-c] file/dir file/dir file/dir
  9.  *
  10.  *  -Nnetid    network identifier
  11.  *
  12.  *  -dlocaldir    local directory to place files
  13.  *
  14.  *  -c        Continue from where you left off before.  Files that already
  15.  *        exist on the local machine will not be re-transfered.  This
  16.  *        will also re-start in the middle of a file that was
  17.  *        partially transfered previously.
  18.  *
  19.  *        This command assumes the file(s) on both machines have not
  20.  *        been modified since the first attempt.    No other checking
  21.  *        is done at the moment.
  22.  */
  23.  
  24. #include "defs.h"
  25.  
  26. void main ARGS((int, char **));
  27.  
  28. typedef struct {
  29.     char    Cmd;
  30.     char    Str[128];
  31.     long    Val;
  32. } HDR;
  33.  
  34.  
  35. extern int Enable_Abort;
  36.  
  37. char Buf[4096];
  38.  
  39. short ContMode;
  40. char  *NetId;
  41. long  LocalDirLock;
  42. void *Chan;
  43.  
  44. void fail ARGS((int));
  45. int CheckNoPath ARGS((char *));
  46. int LostChannel ARGS((void));
  47. void UnknownCmd ARGS((HDR *));
  48. int GetFile ARGS((HDR *, int));
  49. int GetDir ARGS((HDR *, int));
  50. int WriteHeader ARGS((char, char *, long));
  51. int ReadHeader ARGS((HDR *));
  52. char *NSpaces ARGS((int));
  53. int CheckBreak ARGS((void));
  54. void ResetBreak ARGS((void));
  55.  
  56. int brk()
  57. {
  58.     return(0);
  59. }
  60.  
  61.  
  62. void
  63. main(ac,av)
  64. int ac;
  65. char *av[];
  66. {
  67.     HDR Hdr;
  68.     short error;
  69.  
  70.     onbreak(brk);
  71. #ifndef LATTICE
  72.     Enable_Abort = 0;
  73. #endif
  74.     printf("GetFiles V%s%s\n", VERSION, GETFILES_VERSION);
  75.     ResetBreak();
  76.     {
  77.     char *ldir = "";
  78.     FIB *fib = malloc(sizeof(FIB));
  79.     ac = DoOption(ac, av, "N%sd%sc", &NetId, &ldir, &ContMode);
  80.     if (ac <= 1) {
  81.         puts("GETFILES [-Nnetid -dlocaldir -c] remotefile/dir ...");
  82.         fail(22);
  83.     }
  84.     LocalDirLock = Lock(ldir, SHARED_LOCK);
  85.     if (!LocalDirLock && ldir[0]) {     /*  couldn't find it, try to make it */
  86.         if (LocalDirLock = (long)CreateDir(ldir)) {
  87.         UnLock(LocalDirLock);
  88.         LocalDirLock = Lock(ldir, SHARED_LOCK);
  89.         }
  90.     }
  91.     if (!LocalDirLock || !Examine(LocalDirLock, fib) || fib->fib_DirEntryType < 0) {
  92.         printf("Unable to CD or create local directory: \"%s\"\n", ldir);
  93.         fail(21);
  94.     }
  95.     }
  96.     Chan = DOpen(NetId, PORT_GFILECOPY, 126, -80);
  97.     if (!Chan) {
  98.     puts("Unable to connect");
  99.     fail(20);
  100.     }
  101.     error = WriteHeader('H', "Hello, getfiles client V1.30", 0);
  102.     if (error)
  103.     fail(LostChannel());
  104.     switch(ReadHeader(&Hdr)) {
  105.     case -1:
  106.     fail(LostChannel());
  107.     case 'H':
  108.     printf("%s\n", Hdr.Str);
  109.     break;
  110.     }
  111.     {
  112.     short i;
  113.  
  114.     for (i = 1; i < ac; ++i) {
  115.         short error;
  116.  
  117.         error = WriteHeader('G', av[i], 0);
  118.         if (error)
  119.         fail(LostChannel());
  120.         switch(ReadHeader(&Hdr)) {
  121.         case -1:
  122.         fail(LostChannel());
  123.         case 'N':
  124.         printf("Remote error on %s: %s\n", av[i], Hdr.Str);
  125.         break;
  126.         case 'F':
  127.         error = CheckNoPath(Hdr.Str);
  128.         if (!error) {
  129.             long olddir = (long)CurrentDir(LocalDirLock);
  130.             error = GetFile(&Hdr, 0);
  131.             CurrentDir(olddir);
  132.         }
  133.         break;
  134.         case 'D':
  135.         error = CheckNoPath(Hdr.Str);
  136.         if (!error) {
  137.             long olddir = (long)CurrentDir(LocalDirLock);
  138.             error = GetDir(&Hdr, 0);
  139.             CurrentDir(olddir);
  140.         }
  141.         break;
  142.         case 'S':
  143.         printf("Access Violation: %s\n", Hdr.Str);
  144.         break;
  145.         default:
  146.         UnknownCmd(&Hdr);
  147.         error = 1;
  148.         break;
  149.         }
  150.         if (error)
  151.         fail(error);
  152.     }
  153.     if (!error) {
  154.         error = WriteHeader('E', "bye", 0);
  155.         if (error)
  156.         fail(LostChannel());
  157.     }
  158.     }
  159.     fail(0);
  160. }
  161.  
  162. void
  163. fail(code)
  164. {
  165.     if (Chan)
  166.     DClose(Chan);
  167.     if (LocalDirLock)
  168.     UnLock(LocalDirLock);
  169.     exit(code);
  170. }
  171.  
  172. int
  173. CheckNoPath(str)
  174. char *str;
  175. {
  176.     while (*str) {
  177.     if (*str == '/' || *str == ':') {
  178.         puts("SECURITY ALERT: Illegal path spec received");
  179.         return(40);
  180.     }
  181.     ++str;
  182.     }
  183.     return(0);
  184. }
  185.  
  186. int
  187. LostChannel()
  188. {
  189.     puts("DATA CHANNEL LOST");
  190.     return(10);
  191. }
  192.  
  193. void
  194. UnknownCmd(hdr)
  195. HDR *hdr;
  196. {
  197.     printf("UnRecognized command code: %02x\n", hdr->Cmd);
  198. }
  199.  
  200. /*
  201.  *  retrieve a file.  If ContMode set and file exists, try to append to
  202.  *  it.
  203.  */
  204.  
  205. int
  206. GetFile(hdr, stab)
  207. HDR *hdr;
  208. int stab;
  209. {
  210.     long Fh = NULL;
  211.     long pos = 0;
  212.     short error = 0;
  213.  
  214.     printf("%s%-20s ", NSpaces(stab), hdr->Str);
  215.     fflush(stdout);
  216.     if (ContMode) {
  217.     SetProtection(hdr->Str, 0);         /*  make sure it's r/w  */
  218.     if (Fh = Open(hdr->Str, 1005)) {    /*  already exists  */
  219.         long len;
  220.  
  221.         Seek(Fh, 0L, 1);
  222.         len = Seek(Fh, 0L, 0);          /*  get length      */
  223.         if (len > hdr->Val) {
  224.         Close(Fh);
  225.         printf("Cont Error, local file is larger than remote!: %s\n", hdr->Str);
  226.         puts("(not downloaded)");
  227.         return(0);
  228.         }
  229.         if (len == hdr->Val) {
  230.         Close(Fh);
  231.         if (error = WriteHeader('S', NULL, 0))
  232.             return(LostChannel());
  233.         puts("HAVE IT, SKIP");
  234.         return(0);
  235.         }
  236.         printf("(HAVE %ld/%ld) ", len, hdr->Val);
  237.         hdr->Val -= len;        /*  that much less  */
  238.         pos = len;            /*  start at offset */
  239.     }
  240.     }
  241.     if (!Fh) {
  242.     Fh = Open(hdr->Str, 1006);
  243.     if (!Fh) {
  244.         error = WriteHeader('N', "open error", 0);
  245.         printf("Unable to open %s for output\n", hdr->Str);
  246.         if (error)
  247.         return(LostChannel());
  248.         return(1);
  249.     }
  250.     }
  251.     error = WriteHeader('Y', NULL, pos);    /*  yes, gimme gimme    */
  252.  
  253.     /*
  254.      *    Retrieve the data
  255.      */
  256.  
  257.     if (!error) {
  258.     long left = hdr->Val;
  259.     long cnt = pos;
  260.     long total = pos + left;
  261.  
  262.     while (left) {
  263.         long n = (left > sizeof(Buf)) ? sizeof(Buf) : left;
  264.         printf("%6ld/%6ld\23313D", cnt, total);
  265.         fflush(stdout);
  266.         if (DRead(Chan, Buf, n) != n) {
  267.         error = 5;
  268.         break;
  269.         }
  270.         if (CheckBreak()) {
  271.         error = 1;
  272.         break;
  273.         }
  274.         if (Write(Fh, Buf, n) != n) {
  275.         puts("Local Write failed!");
  276.         error = 6;
  277.         break;
  278.         }
  279.         left -= n;
  280.         cnt += n;
  281.         if (CheckBreak()) {
  282.         error = 1;
  283.         break;
  284.         }
  285.     }
  286.     printf("%6ld/%6ld  %s", cnt, total, ((cnt == total) ? "OK" : "INCOMPLETE"));
  287.     }
  288.     Close(Fh);
  289.     puts("");
  290.     if (error) {
  291.     SetProtection(hdr->Str, 10);    /*  disallow reads! */
  292.     return(LostChannel());
  293.     }
  294.     return((int)error);
  295. }
  296.  
  297. /*
  298.  *  Retrieve a directory.  Create it if necessary.
  299.  */
  300.  
  301. int
  302. GetDir(hdr, stab)
  303. HDR *hdr;
  304. int stab;
  305. {
  306.     short error = 0;
  307.     long dirlock;
  308.     static HDR Hdr;        /*    note: static */
  309.  
  310.     if (CheckBreak())
  311.     return(1);
  312.     printf("%s%-20s(DIR)\n", NSpaces(stab), hdr->Str);
  313.     dirlock = Lock(hdr->Str, SHARED_LOCK);  /*  try to lock directory */
  314.     if (!dirlock) {
  315.     if (dirlock = (long)CreateDir(hdr->Str)) {
  316.         UnLock(dirlock);
  317.         dirlock = Lock(hdr->Str, SHARED_LOCK);
  318.     }
  319.     }
  320.     if (!dirlock) {
  321.     error = WriteHeader('N', "couldn't create", 0);
  322.     printf("Unable to create local directory: %s\n", hdr->Str);
  323.     if (error)
  324.         return(LostChannel());
  325.     return(1);
  326.     }
  327.     error = WriteHeader('Y', NULL, 0);  /*  yes, gimme gimme    */
  328.     while (!error) {
  329.     switch(ReadHeader(&Hdr)) {
  330.     case -1:
  331.         error = 1;
  332.         break;
  333.     case 'E':                   /*  end of directory    */
  334.         UnLock(dirlock);
  335.         return(0);
  336.         break;
  337.     case 'F':
  338.         error = CheckNoPath(Hdr.Str);
  339.         if (!error) {
  340.         long olddir = (long)CurrentDir(dirlock);
  341.         error = GetFile(&Hdr, stab + 4);
  342.         CurrentDir(olddir);
  343.         }
  344.         break;
  345.     case 'D':
  346.         error = CheckNoPath(Hdr.Str);
  347.         if (!error) {
  348.         long olddir = (long)CurrentDir(dirlock);
  349.         error = GetDir(&Hdr, stab + 4);
  350.         CurrentDir(olddir);
  351.         }
  352.         break;
  353.     case 'S':
  354.         printf("Access Violation: %s\n", Hdr.Str);
  355.         break;
  356.     case 'N':
  357.         printf("REMOTE ERROR: %s\n", Hdr.Str);
  358.         error = 10;
  359.         break;
  360.     default:
  361.         UnknownCmd(&Hdr);
  362.         error = 1;
  363.         break;
  364.     }
  365.     }
  366.     UnLock(dirlock);
  367.     return(LostChannel());
  368. }
  369.  
  370. int
  371. WriteHeader(c, str, len)
  372. char c;
  373. char *str;
  374. long len;
  375. {
  376.     ubyte sl;
  377.  
  378.     if (str == NULL)
  379.     str = "";
  380.     sl = strlen(str);
  381.  
  382.     if (DWrite(Chan, &c, 1) < 0)
  383.     return(1);
  384.     if (DWrite(Chan, &sl,1) < 0)
  385.     return(1);
  386.     if (DWrite(Chan, str, sl) != sl)
  387.     return(1);
  388.     if (DWrite(Chan, &len, 4) != 4)
  389.     return(1);
  390.     return(0);
  391. }
  392.  
  393. int
  394. ReadHeader(hdr)
  395. HDR *hdr;
  396. {
  397.     ubyte sl;
  398.     ubyte cmd;
  399.  
  400.     hdr->Cmd = -1;
  401.     if (DRead(Chan, &cmd, 1) != 1)
  402.     return(-1);
  403.     if (DRead(Chan, &sl, 1) != 1)
  404.     return(-1);
  405.     if (sl >= sizeof(hdr->Str)) {
  406.     puts("Software error: received file name length too long");
  407.     return(-1);
  408.     }
  409.     if (DRead(Chan, hdr->Str, sl) != sl)
  410.     return(-1);
  411.     hdr->Str[sl] = 0;
  412.     if (DRead(Chan, &hdr->Val, 4) != 4)
  413.     return(-1);
  414.     hdr->Cmd = cmd;
  415.     return((int)hdr->Cmd);
  416. }
  417.  
  418. char *
  419. NSpaces(n)
  420. int n;
  421. {
  422.     static char Buf[128];
  423.     static short in = 0;
  424.     static short last;
  425.  
  426.     if (in == 0) {
  427.     in = 1;
  428.     BSet(Buf, sizeof(Buf)-1, ' ');
  429.     }
  430.     Buf[last] = ' ';
  431.     if (n < 127)
  432.     Buf[n] = 0;
  433.     last = n;
  434.     return(Buf);
  435. }
  436.  
  437. int
  438. CheckBreak()
  439. {
  440.     if (SetSignal(0,0) & (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) {
  441.     puts("^C");
  442.     return(1);
  443.     }
  444.     return(0);
  445. }
  446.  
  447. void
  448. ResetBreak()
  449. {
  450.     SetSignal(0, SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D);
  451. }
  452.  
  453.